using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;

public class MergeTexture : MonoBehaviour
{
    public Texture3D _DstTex;
    public RenderTexture _DstRT;
    public Texture3D _SourceTex;
    
    public ComputeShader copyShader;
    int _SourceTexSize = 150;
    public void OnEnable()
    {
        UpdateSlice_FS();
        //UpdateSlice_CS();
    }

    public void UpdateSlice_FS()
    {
        //
        _SourceTex = new Texture3D(_SourceTexSize, _SourceTexSize, _SourceTexSize, TextureFormat.RGBAHalf, false);
        _SourceTex.filterMode = FilterMode.Trilinear;
        _SourceTex.wrapMode = TextureWrapMode.Clamp;
        
        for (int x = 0; x < _SourceTexSize; x++)
        for (int y = 0; y < _SourceTexSize; y++)
        for (int z = 0; z < _SourceTexSize; z++)
        {
            Color color = new Color((float)x / (float)_SourceTexSize, (float)y / (float)_SourceTexSize, (float)z / (float)_SourceTexSize, 1);
            _SourceTex.SetPixel(x, y, z, color);
        }
        _SourceTex.Apply();

        _DstTex = new Texture3D(_SourceTexSize, _SourceTexSize, _SourceTexSize, TextureFormat.RGBAHalf, false);
        _DstTex.filterMode = FilterMode.Trilinear;
        _DstTex.wrapMode = TextureWrapMode.Clamp;
        _DstTex.Apply();
        
        
        // Material mat = new Material(Shader.Find("Hidden/UpdateSlice"));
        // mat.SetTexture("_SourceTex", _SourceTex);
        // mat.SetTexture("_MainTex", rt3D);
        // mat.SetFloat("_Depth", 150);

        // for (int z = 0; z < 50; z++)
        // {
        //     int sliceIndex = z;
        //     Graphics.SetRenderTarget(rt3D, 0, CubemapFace.Unknown, sliceIndex);
        //     mat.SetFloat("_SliceIndex", sliceIndex);
        //     Graphics.Blit(null, mat);
        //     
        // }

        Update();
    }

    private void Update()
    {
        if (_DstTex == null)
        {
            return;
        }
        
        Profiler.BeginSample("UpdateSlice_FS CopyTexture");
        
        //for (int i = 0; i < 9; i++)
        {
            for (int z = 0; z < 50; z++)
            {
                Graphics.CopyTexture(_SourceTex,z,0,_DstTex,z,0);
            }
        }
        
        Profiler.EndSample();
    }

    public void UpdateSlice_CS()
    {
        //
        _SourceTex = new Texture3D(_SourceTexSize, _SourceTexSize, _SourceTexSize, TextureFormat.RGBAHalf, false);
        _SourceTex.filterMode = FilterMode.Trilinear;
        _SourceTex.wrapMode = TextureWrapMode.Clamp;
        
        for (int x = 0; x < _SourceTexSize; x++)
        for (int y = 0; y < _SourceTexSize; y++)
        for (int z = 0; z < _SourceTexSize; z++)
        {
            Color color = new Color((float)x / (float)_SourceTexSize, (float)y / (float)_SourceTexSize, (float)z / (float)_SourceTexSize, 1);
            _SourceTex.SetPixel(x, y, z, color);
        }
        _SourceTex.Apply();
        //

        _DstRT = new RenderTexture(_SourceTexSize, _SourceTexSize, 0);
        _DstRT.dimension = UnityEngine.Rendering.TextureDimension.Tex3D;
        _DstRT.volumeDepth = 150;
        _DstRT.enableRandomWrite = true;
        _DstRT.format = RenderTextureFormat.ARGBHalf;
        _DstRT.wrapMode = TextureWrapMode.Clamp;
        _DstRT.filterMode = FilterMode.Trilinear;
        _DstRT.Create();
        
        
        // 调度 ComputeShader
        int kernel = copyShader.FindKernel("CSMain");
        copyShader.SetTexture(kernel, "_SourceTex", _SourceTex);
        copyShader.SetTexture(kernel, "_TargetTex", _DstRT);
        copyShader.SetInts("_TargetOffset", 0,0,0);
        copyShader.SetInts("_SourceSize", _SourceTexSize, _SourceTexSize, _SourceTexSize);
        
        int threadGroupX = Mathf.CeilToInt(_SourceTexSize / 4.0f);
        int threadGroupY = Mathf.CeilToInt(_SourceTexSize / 4.0f);
        int threadGroupZ = Mathf.CeilToInt(_SourceTexSize / 4.0f);
        
        copyShader.Dispatch(kernel, threadGroupX, threadGroupY, threadGroupZ);
    }
}

